package org.nebuloop.photo.organizer.util;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.configuration.MapConfiguration;
import org.nebuloop.photo.organizer.DestDirCreator;
import org.nebuloop.photo.organizer.ImageProcessor;

import com.drew.imaging.ImageMetadataReader;
import com.drew.lang.GeoLocation;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;
import com.drew.metadata.exif.ExifIFD0Directory;
import com.drew.metadata.exif.ExifSubIFDDirectory;
import com.drew.metadata.exif.GpsDirectory;

/**
 * Prints Exif information about an image
 */
public class ImageExifSampler {

  public static final Logger LOGGER = Logger.getLogger(ImageExifSampler.class.getName());

  public static void main(String... args) {
    if (args.length > 0) {
      for (String arg : args) {
        execute(arg);
      }
    } else {
      for (String arg : new String[] { "/Users/bverma/photos/unsorted/2013/03/2013-03-27/IMG035.jpg"
          , "/Users/bverma/photos/main/2013/04/2013-04-27_Canon_PowerShot_SD980_IS/IMG_8032.JPG"
          ,"/Users/bverma/Pictures/IMG_0252.JPG"
          ,"/Users/bverma/photos/main/2013/08/2013-08-11_Apple_iPhone_5/IMG_0169.JPG"
      }) {
        execute(arg);
      }
    }
  }

  public static void execute(String strImage) {
    try {
      File imageFile = new File(strImage);
      System.out.println("Processing file " + imageFile.getCanonicalPath());
      Metadata metadata = ImageMetadataReader.readMetadata(imageFile);
//          ExifSubIFDDirectory exifDir = metadata.getDirectory(ExifSubIFDDirectory.class);
//
//          if (exifDir == null) {
//              throw new IOException("No Exif Data found for image "
//                      + imageFile.getAbsolutePath());
//          }
//          Collection<Tag> tags = exifDir.getTags();
//          for (Tag tag:tags) {
//              System.out.println(tag);
//          }
      for (Directory directory : metadata.getDirectories()) {
        for (Tag tag : directory.getTags()) {
          System.out.println(tag);
        }
      }
      ExifSubIFDDirectory exifSubIFDDir = metadata.getDirectory(ExifSubIFDDirectory.class);
      ExifIFD0Directory exifIFD0Dir = metadata.getDirectory(ExifIFD0Directory.class);
      GpsDirectory gpsDir = metadata.getDirectory(GpsDirectory.class);
      Date imageCreateTime = ImageProcessor.extractImageDate(exifSubIFDDir, exifIFD0Dir);
      LOGGER.log(Level.FINE, "Image Create Date : {0,date,yyyy-MM-dd HH:mm:ss}", imageCreateTime);

      Map<String, String> props = new HashMap<>();
      props.put(Config.DEST_DIR_PATTERN, "${yyyy}/${mm}/${yyyy}-${mm}-${dd}--${camera.make}-${camera.model}");
      MapConfiguration config = new MapConfiguration(props);
      Config.setConfiguraiton(config);
      DestDirCreator destDirCreator = DestDirCreator.getInstance();
      destDirCreator.setPreserveNonNumericFolderName(false);
      destDirCreator.setUseCameraInFolderName(true);
      String strDestDir = destDirCreator.getImageOutputPath(imageFile,
          System.getProperty("user.home"), metadata, imageCreateTime);

      LOGGER.info("Destination Directory : " + strDestDir);
      
      boolean hasGeocodes =  (gpsDir != null && gpsDir.getGeoLocation() != null);
      LOGGER.info("Image has GeoTags : " + hasGeocodes);
      if (hasGeocodes) {
        GeoLocation geoLoc = gpsDir.getGeoLocation();
        LOGGER.info("GeoTags : "  + geoLoc);
      }
      
    } catch (Exception ex) {
      LOGGER.log(Level.SEVERE, "", ex);
      ex.printStackTrace();
    }
  }
  
  public static void execute_old(String strImage) {
    try {
      File imageFile = new File(strImage);
      System.out.println("Processing file " + imageFile.getCanonicalPath());
      Metadata metadata = ImageMetadataReader.readMetadata(imageFile);
//			ExifSubIFDDirectory exifDir = metadata.getDirectory(ExifSubIFDDirectory.class);
//
//			if (exifDir == null) {
//				throw new IOException("No Exif Data found for image "
//						+ imageFile.getAbsolutePath());
//			}
//			Collection<Tag> tags = exifDir.getTags();
//			for (Tag tag:tags) {
//				System.out.println(tag);
//			}
      for (Directory directory : metadata.getDirectories()) {
        for (Tag tag : directory.getTags()) {
          System.out.println(tag);
        }
      }
      ExifSubIFDDirectory exifSubIFDDir = metadata.getDirectory(ExifSubIFDDirectory.class);
      ExifIFD0Directory exifIFD0Dir = metadata.getDirectory(ExifIFD0Directory.class);
      GpsDirectory gpsDir = metadata.getDirectory(GpsDirectory.class);
      Date imageCreateTime = ImageProcessor.extractImageDate(exifSubIFDDir, exifIFD0Dir);
      LOGGER.log(Level.FINE, "Image Create Date : {0,date,yyyy-MM-dd HH:mm:ss}", imageCreateTime);
      String cameraMake = exifIFD0Dir.getString(ExifIFD0Directory.TAG_MAKE);
      String cameraModel = exifIFD0Dir.getString(ExifIFD0Directory.TAG_MODEL);

      DestDirCreator destDirCreator = DestDirCreator.getInstance();
      destDirCreator.setPreserveNonNumericFolderName(false);
      destDirCreator.setUseCameraInFolderName(true);
      String strDestDir = destDirCreator.getImageOutputPath(metadata, imageCreateTime, imageFile,
          System.getProperty("user.home"), cameraMake, cameraModel);

      LOGGER.info("Destination Directory : " + strDestDir);
      
      boolean hasGeocodes =  (gpsDir != null && gpsDir.getGeoLocation() != null);
      LOGGER.info("Image has GeoTags : " + hasGeocodes);
      if (hasGeocodes) {
        GeoLocation geoLoc = gpsDir.getGeoLocation();
        LOGGER.info("GeoTags : "  + geoLoc);
      }
      
    } catch (Exception ex) {
      LOGGER.log(Level.SEVERE, "", ex);
      ex.printStackTrace();
    }
  }
}
